/**
 * @file
 * @brief 应用程序入口
 * @author
 * + 隐星魂 (Roy Sun) <xwos@xwos.tech>
 * @copyright
 * + Copyright © 2015 xwos.tech, All Rights Reserved.
 * > Licensed under the Apache License, Version 2.0 (the "License");
 * > you may not use this file except in compliance with the License.
 * > You may obtain a copy of the License at
 * >
 * >         http://www.apache.org/licenses/LICENSE-2.0
 * >
 * > Unless required by applicable law or agreed to in writing, software
 * > distributed under the License is distributed on an "AS IS" BASIS,
 * > WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * > See the License for the specific language governing permissions and
 * > limitations under the License.
 */

#include "board/std.h"
#include <string.h>
#include <xwos/lib/xwlog.h>
#include <xwos/osal/thd.h>
#include <xwcd/ds/soc/gpio.h>
#include "RTD/mif.h"
#include "RTD/xwds/device.h"
#include "RTD/gpio.h"
#include "App/button.h"
#include "App/canbus.h"
#include "Tst/eeprom.h"
#include "Tst/w25qxx.h"

#define LOGTAG "Mtask"
#define MTASK_LOG
#ifdef MTASK_LOG
#  define mtasklogf(lv, fmt, ...) \
          xwlogf(lv, LOGTAG, fmt, ##__VA_ARGS__)
#else
#  define mtasklogf(lv, fmt, ...)
#endif

#define MAIN_THD_PRIORITY XWOS_SKD_PRIORITY_DROP(XWOS_SKD_PRIORITY_RT_MAX, 0)
xwer_t main_task(void * arg);
struct xwos_thd main_thd;
xwos_thd_d main_thdd;
__xwcc_aligned(16) xwu8_t main_thd_stack[8192] = {0};

xwer_t xwos_main(void)
{
        xwer_t rc;
        struct xwos_thd_attr attr;

        xwos_thd_attr_init(&attr);
        attr.name = "main.thd";
        attr.stack = (xwstk_t *)main_thd_stack;
        attr.stack_size = sizeof(main_thd_stack);
        attr.priority = MAIN_THD_PRIORITY;
        attr.detached = true;
        attr.privileged = true;
        rc = xwos_thd_init(&main_thd, &main_thdd,
                           &attr,
                           main_task,
                           NULL);
        if (rc < 0) {
                goto err_thd_init;
        }

        rc = xwos_skd_start_lc();
        if (rc < 0) {
                goto err_skd_start_lc;
        }
        return XWOK;

err_skd_start_lc:
        XWOS_BUG();
err_thd_init:
        XWOS_BUG();
        return rc;
}

xwer_t main_task(void * arg)
{
        XWOS_UNUSED(arg);
        rtd_start();
        button_start();
        tst_eeprom_read();
        tst_w25qxx_init();
        canbus0_init();
        xwds_gpio_req(&rtdxwds_soc, GPO_LED_BLUE_PORT, GPO_LED_BLUE_PIN);
        xwds_gpio_set(&rtdxwds_soc, GPO_LED_BLUE_PORT, GPO_LED_BLUE_PIN);
        while (!xwos_cthd_shld_stop()) {
                if (xwos_cthd_shld_frz()) {
                        xwds_gpio_reset(&rtdxwds_soc,
                                        GPO_LED_BLUE_PORT, GPO_LED_BLUE_PIN);
                        xwds_gpio_rls(&rtdxwds_soc,
                                      GPO_LED_BLUE_PORT, GPO_LED_BLUE_PIN);
                        xwos_cthd_freeze();
                        xwds_gpio_req(&rtdxwds_soc,
                                      GPO_LED_BLUE_PORT, GPO_LED_BLUE_PIN);
                }
                xwos_cthd_sleep(xwtm_s(1));
                xwds_gpio_toggle(&rtdxwds_soc,
                                 GPO_LED_BLUE_PORT, GPO_LED_BLUE_PIN);
        }
        xwds_gpio_rls(&rtdxwds_soc, GPO_LED_BLUE_PORT, GPO_LED_BLUE_PIN);
        return XWOK;
}
